
package com.platform.modules.app.controller;

import cn.binarywang.wx.miniapp.api.WxMaQrcodeService;
import cn.binarywang.wx.miniapp.bean.WxMaCodeLineColor;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.platform.annotation.IgnoreAuth;
import com.platform.annotation.LoginUser;
import com.platform.common.exception.BusinessException;
import com.platform.common.utils.*;
import com.platform.modules.mall.dao.MallShopsDao;
import com.platform.modules.mall.dao.MallShopsGoodsDao;
import com.platform.modules.mall.entity.*;
import com.platform.modules.mall.service.*;
import com.platform.modules.mch.entity.MchGoodsExtendEntity;
import com.platform.modules.mch.service.MchGoodsExtendService;
import com.platform.modules.oss.cloud.UploadFactory;
import com.platform.modules.sys.service.SysConfigService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author
 */
@Slf4j
@RestController
@RequestMapping("/app/goods")
@Api(tags = "AppGoodsController|商品接口")
public class AppGoodsController extends AppBaseController {
    @Autowired
    private MallGoodsService goodsService;
    @Autowired
    private MallFootprintService footprintService;
    @Autowired
    private MallUserService userService;
    @Autowired
    private MallIssueService issueService;
    @Autowired
    private MallCardShopsService cardShopsService;
    @Autowired
    private MallCommentService commentService;
    @Autowired
    private MallCommentPictureService commentPictureService;
    @Autowired
    private MallCollectService collectService;
    @Autowired
    private WxMaQrcodeService maQrcodeService;
    @Autowired
    private MallCategoryService categoryService;
    @Autowired
    private MallShopsGoodsService shopsGoodsService;
    @Autowired
    private MallGoodsInstallmentsService goodsInstallmentsService;
    @Autowired
    private MallShopsService shopsService;
    @Autowired
    private SysConfigService sysConfigService;
    @Resource
    private MchGoodsExtendService mchGoodsExtendService;
    @Resource
    private JedisUtil jedisUtil;

    @Value("${wx.config.envVersion}")
    private String envVersion;

    /**
     * 热销、新品推荐列表
     */
    @IgnoreAuth
    @GetMapping("/list")
    @ApiOperation(value = "热销、新品推荐列表", notes = "热销、新品推荐列表")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "type", value = "类型：IS_HOT：热销商品；IS_NEW：新品推荐", allowableValues = "IS_HOT,IS_NEW", dataType = "string"),
            @ApiImplicitParam(paramType = "query", name = "categoryId", value = "分类ID", dataType = "string"),
            @ApiImplicitParam(paramType = "query", name = "order", value = "排序字段", allowableValues = "RETAIL_PRICE,SALES", dataType = "string"),
            @ApiImplicitParam(paramType = "query", name = "sortType", value = "排序类型", allowableValues = "ASC,DESC", dataType = "string"),
            @ApiImplicitParam(paramType = "query", name = "current", value = "当前页码", example = "1", dataType = "int"),
            @ApiImplicitParam(paramType = "query", name = "limit", value = "每页条数", example = "10", dataType = "int")
    })
    public RestResponse list(String categoryId, String type, String order, String sortType, @RequestParam(defaultValue = "1") Integer current, @RequestParam(defaultValue = "10") Integer limit) {
        Page<MallGoodsEntity> page = new Page<>(current, limit);

        IPage<MallGoodsEntity> data = goodsService.page(page, new QueryWrapper<MallGoodsEntity>()
                .eq(StringUtils.isNotBlank(categoryId), "CATEGORY_ID", categoryId)
                .eq(StringUtils.isNotBlank(type), type, 1).eq("IS_ON_SALE", 1)
                .orderBy(StringUtils.isNotBlank(order), "ASC".equalsIgnoreCase(sortType), order).orderByDesc("SORT"));

        return RestResponse.success().put("data", data);
    }


    /**
     * 热销、新品推荐列表，店铺相关的商品
     */
    @IgnoreAuth
    @GetMapping("/dplist")
    @ApiOperation(value = "所有店铺的商品", notes = "所有店铺的商品")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "type", value = "类型：IS_HOT：热销商品；IS_NEW：新品推荐", allowableValues = "IS_HOT,IS_NEW", dataType = "string"),
            @ApiImplicitParam(paramType = "query", name = "order", value = "排序字段", allowableValues = "RETAIL_PRICE,SALES", dataType = "string"),
            @ApiImplicitParam(paramType = "query", name = "sortType", value = "排序类型", allowableValues = "ASC,DESC", dataType = "string"),
            @ApiImplicitParam(paramType = "query", name = "current", value = "当前页码", example = "1", dataType = "int"),
            @ApiImplicitParam(paramType = "query", name = "limit", value = "每页条数", example = "10", dataType = "int")
    })
    public RestResponse dplist(String type, String order, String sortType,
                               @RequestParam(defaultValue = "1") Integer current, @RequestParam(defaultValue = "10") Integer limit) {

        String dp_id = sysConfigService.getValue("DP_ID");
        Page<MallGoodsEntity> page = new Page<>(current, limit);

        IPage<MallGoodsEntity> data = goodsService.page(page, new QueryWrapper<MallGoodsEntity>()
                .eq(StringUtils.isNotBlank(dp_id), "CATEGORY_ID", dp_id)
                .eq(StringUtils.isNotBlank(type), type, 1).eq("IS_ON_SALE", 1)
                .orderBy(StringUtils.isNotBlank(order), "ASC".equalsIgnoreCase(sortType), order).orderByDesc("SORT"));

        return RestResponse.success().put("data", data);
    }

    /**
     * 热销、新品推荐列表，店铺相关的商品
     */
    @IgnoreAuth
    @GetMapping("/llgoods")
    @ApiOperation(value = "查询联联商品", notes = "查询联联商品")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "type", value = "类型：IS_HOT：热销商品；IS_NEW：新品推荐", allowableValues = "IS_HOT,IS_NEW", dataType = "string"),
            @ApiImplicitParam(paramType = "query", name = "order", value = "排序字段", allowableValues = "RETAIL_PRICE,SALES", dataType = "string"),
            @ApiImplicitParam(paramType = "query", name = "sortType", value = "排序类型", allowableValues = "ASC,DESC", dataType = "string"),
            @ApiImplicitParam(paramType = "query", name = "current", value = "当前页码", example = "1", dataType = "int"),
            @ApiImplicitParam(paramType = "query", name = "limit", value = "每页条数", example = "10", dataType = "int")
    })
    public RestResponse llGoods(String type, String order, String sortType,
                               @RequestParam(defaultValue = "1") Integer current, @RequestParam(defaultValue = "10") Integer limit) {
        Page<MallGoodsEntity> page = new Page<>(current, limit);
        IPage<MallGoodsEntity> data = goodsService.page(page, new QueryWrapper<MallGoodsEntity>()
                .eq(StringUtils.isNotBlank(type), type, 1)
                .eq("GOODS_TYPE", MallGoodsEntity.GoodsType.LL.ordinal())
                .eq("IS_ON_SALE", 1)
                .orderBy(StringUtils.isNotBlank(order), "ASC".equalsIgnoreCase(sortType), order)
                .orderByDesc("SORT"));

        // 联联商品单独查询
        data.getRecords()
                .parallelStream()
                .forEach(x->{
                    String htmlContent = jedisUtil.getCache(Constant.LL_GOODS_EXTEND+x.getId(),()->Optional.ofNullable(mchGoodsExtendService.getById(x.getId())).map(MchGoodsExtendEntity::getHtmlContent).orElse(""), String.class);
                    x.setGoodsDesc(htmlContent);
                });
        return RestResponse.success().put("data", data);
    }

    /**
     * 根据1级分类获取下面所有的商品
     */
    @IgnoreAuth
    @GetMapping("/listByCategory")
    @ApiOperation(value = "热销、新品推荐列表", notes = "热销、新品推荐列表")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "type", value = "类型：IS_HOT：热销商品；IS_NEW：新品推荐", allowableValues = "IS_HOT,IS_NEW", dataType = "string"),
            @ApiImplicitParam(paramType = "query", name = "categoryId", value = "分类ID", dataType = "string"),
            @ApiImplicitParam(paramType = "query", name = "order", value = "排序字段", allowableValues = "RETAIL_PRICE,SALES", dataType = "string"),
            @ApiImplicitParam(paramType = "query", name = "sortType", value = "排序类型", allowableValues = "ASC,DESC", dataType = "string"),
            @ApiImplicitParam(paramType = "query", name = "current", value = "当前页码", example = "1", dataType = "int"),
            @ApiImplicitParam(paramType = "query", name = "limit", value = "每页条数", example = "10", dataType = "int")
    })
    public RestResponse listByCategory(String categoryId, String type, String order, String sortType
            , @RequestParam(defaultValue = "1") Integer current, @RequestParam(defaultValue = "10") Integer limit) {
        MallCategoryEntity currentCategory = categoryService.getById(categoryId);
        //获取子分类数据
        if (null != currentCategory) {
            Map<String, Object> params = new HashMap<>(4);
            params.put("isShow", 1);
            params.put("parentId", categoryId);
            currentCategory.setSubCategoryList(categoryService.queryAll(params));
            List<String> sub = categoryService.queryAll(params).stream().map(MallCategoryEntity::getId).collect(Collectors.toList());
            Page<MallGoodsEntity> page = new Page<>(current, limit);
            IPage<MallGoodsEntity> data = goodsService.page(page, new QueryWrapper<MallGoodsEntity>()
                    .in("CATEGORY_ID", sub)
                    .eq(StringUtils.isNotBlank(type), type, 1).eq("IS_ON_SALE", 1)
                    .orderBy(StringUtils.isNotBlank(order), "ASC".equalsIgnoreCase(sortType), order).orderByDesc("SORT"));
            return RestResponse.success().put("data", data);
        }
        return RestResponse.success().put("data", null);
    }

    /**
     * 获取店铺卡卷列表
     */
    @IgnoreAuth
    @GetMapping("getCardListByShopId")
    @ApiOperation(value = "获取店铺卡卷列表", notes = "获取店铺卡卷列表")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "current", value = "当前页码", example = "1", dataType = "int"),
            @ApiImplicitParam(paramType = "query", name = "limit", value = "每页条数", example = "10", dataType = "int"),
            @ApiImplicitParam(paramType = "query", name = "isHot", value = "是否热销，首页接口使用传值1，其他地方使用不传参", example = "", dataType = "int"),
            @ApiImplicitParam(paramType = "query", name = "shopsId", value = "店铺id", example = "10", dataType = "string")
    })
    public RestResponse getCardListByShopId(@RequestParam(defaultValue = "") String shopsId, @RequestParam(defaultValue = "1") Integer current,
                                            @RequestParam(defaultValue = "50") Integer limit) {
        if ("".equals(shopsId)) {
            return RestResponse.error("数据请求失败");
        }
        Map<String, Object> params = new HashMap<>(10);
        params.put("page", current);
        params.put("limit", limit);
        params.put("shopsId", shopsId);
        params.put("isOnSale", 1);
        params.put("activityOnly", 0);
        IPage data = cardShopsService.queryPageUnionCard(params);
        ArrayList<Map<String, Object>> goods = new ArrayList<>(50);
        ArrayList<Map<String, Object>> setMeal = new ArrayList<>(50);
        ArrayList<Map<String, Object>> card = new ArrayList<>(50);
        for (Map<String, Object> item : (List<Map<String, Object>>) data.getRecords()) {
            if (0 == (Integer) item.get("goodsType")) {
                goods.add(item);
            } else if (1 == (Integer) item.get("setMeal")) {
                card.add(item);
            } else {
                setMeal.add(item);
            }
        }
        return RestResponse.success().put("card", card).put("setMeal", setMeal).put("goods", goods);
    }


    /**
     * 商品分期规格
     */
    @IgnoreAuth
    @GetMapping("/goodsInstallments")
    @ApiOperation(value = "商品分期规格", notes = "商品分期规格")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "goodsId", value = "商品id", example = "10", dataType = "string")
    })
    public RestResponse goodsInstallments(String goodsId) {

        if (StringUtils.isBlank(goodsId)) {
            return RestResponse.error("缺少参数");
        }

        // 显示是最高期的显示在最后面所以按照升序取第一个
        List<MallGoodsInstallmentsEntity> goodsInstallmentsEntityList = goodsInstallmentsService.list(new LambdaQueryWrapper<MallGoodsInstallmentsEntity>()
                .eq(MallGoodsInstallmentsEntity::getGoodsId, goodsId).orderByAsc(MallGoodsInstallmentsEntity::getSort));

        return RestResponse.success().put("data", goodsInstallmentsEntityList);
    }

    /**
     * 商品详情
     */
    @GetMapping("/detail")
    @ApiOperation(value = "商品详情", notes = "根据ID查询商品详情")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "header", name = "token", value = "用户token", required = true, dataType = "string"),
            @ApiImplicitParam(paramType = "query", name = "goodsId", value = "商品ID", example = "1", required = true, dataType = "string")
    })
    public RestResponse detail(String goodsId,String location) {
        String userId = getUserId();
        Map<String, Object> resultObj = new HashMap<>();
        MallGoodsEntity info = goodsService.queryById(goodsId);
        if(info == null){
            return  RestResponse.error("商品详情");
        }
//        String discountsIntegralGoods = sysConfigService.getValue(Constant.DISCOUNTS_INTEGRAL_GOODS);
//        if (discountsIntegralGoods != null && discountsIntegralGoods.indexOf(goodsId) >= 0) {
//            BigDecimal discountsIntegral = BigDecimal.valueOf(Short.parseShort(sysConfigService.getValue(Constant.DISCOUNTS_INTEGRAL, "0")));
//            info.setCustomerIntegral(info.getCustomerIntegral().subtract(discountsIntegral));
//        }
//        MallShopsGoodsEntity shopsGoodsEntity = shopsGoodsService.getOne(new LambdaQueryWrapper<MallShopsGoodsEntity>().eq(MallShopsGoodsEntity::getGoodsId, goodsId), false);
//        if (null != shopsGoodsEntity) {
//            info.setShopsId(shopsGoodsEntity.getShopsId());
//        }
        // 记录用户的足迹 同一商品只记录最后访问时间
        MallFootprintEntity footprintEntity = footprintService.getOne(
                new QueryWrapper<MallFootprintEntity>().eq("USER_ID", userId).eq("GOODS_ID", goodsId), false);
        if (footprintEntity == null) {
            footprintEntity = new MallFootprintEntity();
        }
        footprintEntity.setAddTime(new Date());
        footprintEntity.setUserId(userId);
        footprintEntity.setGoodsId(goodsId);
        footprintService.saveOrUpdate(footprintEntity);
        resultObj.put("info", info);
        resultObj.put("count",((MallShopsGoodsDao)shopsGoodsService.getBaseMapper()).getGoodsShopsCount(goodsId));


        if(StringUtils.isNotBlank(location)){
            String distance = String.format("FLOOR(ST_Distance( ST_GeomFromText ( 'point(%s)',4326), location))  distance",location.replace(","," "));
            Map<String,Object> map = new HashMap<>(8);
            map.put("goodsId",goodsId);
            map.put("sortName", "distance");
            map.put("select",String.format("S.id,S.name,S.details,%s,S.telephone,S.shop_score,S.average_price,S.IMG_URL",distance));
            resultObj.put("shops",((MallShopsDao)shopsService.getBaseMapper()).getShopsInfo(null,map));
        }else{
            List<MallShopsEntity> shopslist = shopsGoodsService.selectShopsByGoodsId(goodsId);
            resultObj.put("shops",shopslist);
        }

        return RestResponse.success().put("data", resultObj);
    }

    /**
     * 商品详情
     */
    @GetMapping("/otherDetail")
    @ApiOperation(value = "商品详情", notes = "根据ID查询商品详情")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "header", name = "token", value = "用户token", required = true, dataType = "string"),
            @ApiImplicitParam(paramType = "query", name = "goodsId", value = "商品ID", example = "1", required = true, dataType = "string")
    })
    public RestResponse otherDetail(@LoginUser MallUserEntity user, String goodsId) {
        Map<String, Object> resultObj = new HashMap<>();
        List<MallIssueEntity> issue = issueService.list();
        //
        QueryWrapper<MallCommentEntity> commentQuery = new QueryWrapper<MallCommentEntity>().eq("GOODS_ID", goodsId).eq("STATUS", 1);
        Integer commentCount = commentService.count(commentQuery);
        List<MallCommentEntity> hotComment = commentService.list(commentQuery);
        Map<String, Object> commentInfo = new HashMap<>();
        if (null != hotComment && hotComment.size() > 0) {
            MallUserEntity commentUser = userService.getById(hotComment.get(0).getUserId());
            commentInfo.put("content", Base64Util.decode(hotComment.get(0).getContent()));
            commentInfo.put("addTime", DateUtils.format(hotComment.get(0).getAddTime(), DateUtils.DATE_PATTERN));
            commentInfo.put("nickname", commentUser.getNickname());
            commentInfo.put("headImgUrl", commentUser.getHeadImgUrl());
            List<MallCommentPictureEntity> commentPictureEntities = commentPictureService.list(
                    new QueryWrapper<MallCommentPictureEntity>().eq("comment_id", hotComment.get(0).getId()));
            commentInfo.put("picList", commentPictureEntities);
        }
        Map<String, Object> comment = new HashMap<>(4);
        comment.put("count", commentCount);
        comment.put("data", commentInfo);
        //当前用户是否收藏
        Integer userHasCollect = collectService.count(new QueryWrapper<MallCollectEntity>().eq("USER_ID", user.getId()).eq("GOODS_ID", goodsId));
        if (userHasCollect > 0) {
            userHasCollect = 1;
        }
        //
        resultObj.put("userHasCollect", userHasCollect);
        resultObj.put("issue", issue);
        resultObj.put("comment", comment);
        return RestResponse.success().put("data", resultObj);
    }

    /**
     * 商品总计
     */
    @IgnoreAuth
    @GetMapping("/count")
    @ApiOperation(value = "商品总计", notes = "商品总计")
    public RestResponse count() {
        return RestResponse.success().put("data", goodsService.count(new QueryWrapper<MallGoodsEntity>().eq("IS_ON_SALE", 1)));
    }


    /**
     * 新品首发
     */
    @IgnoreAuth
    @GetMapping("newBanner")
//    @ApiOperation(value = "新品首发banner", notes = "新品首发顶部展示信息")
    public RestResponse newBanner() {
        Map<String, Object> bannerInfo = new HashMap<>(8);
        bannerInfo.put("url", "");
        bannerInfo.put("name", "坚持初心，为你寻觅世间好物");
        bannerInfo.put("imgUrl", "https://platform-wxmall.oss-cn-beijing.aliyuncs.com/grocery/new.png");
        return RestResponse.success().put("data", bannerInfo);
    }

    /**
     * 人气推荐
     */
    @IgnoreAuth
    @GetMapping("hotBanner")
//    @ApiOperation(value = "人气推荐banner", notes = "人气推荐顶部展示信息")
    public RestResponse hotBanner() {
        Map<String, Object> bannerInfo = new HashMap<>();
        bannerInfo.put("url", "");
        bannerInfo.put("name", "大家都在买的好物");
        bannerInfo.put("imgUrl", "https://platform-wxmall.oss-cn-beijing.aliyuncs.com/grocery/hot.png");
        return RestResponse.success().put("data", bannerInfo);
    }

    /**
     * 获取商品小程序码
     *
     * @param user
     * @param goodsId
     * @param width
     * @return
     */
    @GetMapping("/getGoodsQrCode")
    @ApiOperation(value = "获取商品小程序码", notes = "获取商品小程序码")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "header", name = "token", value = "用户token", required = true, dataType = "string"),
            @ApiImplicitParam(paramType = "query", name = "goodsId", value = "商品ID", example = "1", required = true, dataType = "string"),
            @ApiImplicitParam(paramType = "query", name = "width", value = "小程序码宽度", example = "250", required = true, dataType = "string")
    })
    public RestResponse getGoodsQrCode(@LoginUser MallUserEntity user, String goodsId, @RequestParam(defaultValue = "250") Integer width) {
        String page = "/pages/goods/goods?id=" + goodsId + "&referrer=" + user.getId();
        try {
            byte[] bytes = maQrcodeService.createWxaCodeBytes(page,envVersion,width, false, new WxMaCodeLineColor("0", "0", "0"), true);

            String url = UploadFactory.build().uploadSuffix(bytes, ".png");

            return RestResponse.success().put("url", url);
        } catch (WxErrorException e) {
            e.printStackTrace();
            throw new BusinessException("获取小程序码失败！");
        }
    }


}
